#ifndef _GPIO_HW_H_
#define _GPIO_HW_H_

#include "soc.h"

typedef struct
{
	_RW MODER;    /*!< GPIO port mode register,               offset: 0x00      */
	_RW OTYPER;   /*!< GPIO port output type register,        offset: 0x04      */
	_RW OSPEEDR;  /*!< GPIO port output speed register,       offset: 0x08      */
	_RW PUPDR;    /*!< GPIO port pull-up/pull-down register,  offset: 0x0C      */
	_OR IDR;      /*!< GPIO port input data register,         offset: 0x10      */
	_RW ODR;      /*!< GPIO port output data register,        offset: 0x14      */
	_RW BSRR;     /*!< GPIO port bit set/reset register,      offset: 0x18      */
	_RW LCKR;     /*!< GPIO port configuration lock register, offset: 0x1C      */
	_RW AFLR;     /*!< GPIO alternate function registers,     offset: 0x20 */
	_RW AFHR;     /*!< GPIO alternate function registers,     offset: 0x24 */
} GPIO_Struct;

extern GPIO_Struct SOC_GPIOA;
extern GPIO_Struct SOC_GPIOB;
extern GPIO_Struct SOC_GPIOC;
extern GPIO_Struct SOC_GPIOD;
extern GPIO_Struct SOC_GPIOE;
extern GPIO_Struct SOC_GPIOF;
extern GPIO_Struct SOC_GPIOG;
extern GPIO_Struct SOC_GPIOH;
extern GPIO_Struct SOC_GPIOI;

/**
 * 配置输入、输出、复用、模拟，配置为模拟时，不能5V容忍。对于系统IO，不再像F1
 * 那样需要配置AFIO模块，仅需要配置MODER_IN/OUT即可
 */
#define GPIO_MODER_MASK(pin)      (0x3U<<((pin)*2))
#define GPIO_MODER_IN(pin)        (0x0U<<((pin)*2))
#define GPIO_MODER_OUT(pin)       (0x1U<<((pin)*2))
#define GPIO_MODER_AF(pin)        (0x2U<<((pin)*2))
#define GPIO_MODER_ANALOG(pin)    (0x3U<<((pin)*2))

/**
 * 配置推挽、开漏
 */
#define GPIO_OTYPER_MASK(pin)     (0x1U<<((pin)*1))
#define GPIO_OTYPER_PP(pin)       (0x0U<<((pin)*1))
#define GPIO_OTYPER_OD(pin)       (0x1U<<((pin)*1))

/**
 * 配置速度，30pF时最大为100MHz，15pF时最大为80MHz
 */
#define GPIO_OSPEEDR_MASK(pin)    (0x3U<<((pin)*2))
#define GPIO_OSPEEDR_2M(pin)      (0x0U<<((pin)*2))
#define GPIO_OSPEEDR_25M(pin)     (0x1U<<((pin)*2))
#define GPIO_OSPEEDR_50M(pin)     (0x2U<<((pin)*2))
#define GPIO_OSPEEDR_100M(pin)    (0x3U<<((pin)*2))

/**
 * 配置上拉、下拉
 */
#define GPIO_PUPDR_MASK(pin)      (0x3U<<((pin)*2))
#define GPIO_PUPDR_NONE(pin)      (0x0U<<((pin)*2))
#define GPIO_PUPDR_UP(pin)        (0x1U<<((pin)*2))
#define GPIO_PUPDR_DOWN(pin)      (0x2U<<((pin)*2))

/**
 * 配置复用
 */
#define GPIO_AFLR_MASK(pin)       (0xFU<<((pin)*4))
#define GPIO_AFLR_0_15D(pin, val) ((val)<<((pin)*4))
#define GPIO_AFHR_MASK(pin)       (0xFU<<(((pin)-8)*4))
#define GPIO_AFHR_0_15D(pin, val) ((val)<<(((pin)-8)*4))

/**
 * 置位/清零，如果同时设置了则置位优先
 */
#define GPIO_BSRR_SET(pin)        (0x1U<<((pin)+0))
#define GPIO_BSRR_CLEAR(pin)      (0x1U<<((pin)+16))

#endif /* _GPIO_HW_H_ */
